import AudioManager from "./AudioManager";
import DataCenter from "./DataCenter";
import Board from "./Game/Board";
import { Mino } from "./Game/Mino";
import MainUI from "./MainUI";
import SpeedManager from "./SpeedManager";

const { ccclass, property } = cc._decorator;

@ccclass
export default class GameLogic extends cc.Component {
    private p_Paused = false;
    private p_GameStarted = false;
    private p_StartGameTS = 0;

    private interval = 1;
    private speed = 1;

    @property(Board)
    board: Board = null;

    @property(MainUI)
    mainUI: MainUI = null;

    @property(AudioManager)
    audio: AudioManager = null;

    protected onLoad(): void {
        if (CC_DEBUG) {
            (window as any).GameLogic = this;
        }
    }

    protected onEnable(): void {
        this.node.on('go-up', this.onGoUp, this);
        this.node.on('go-down', this.onGoDown, this);
        this.node.on('go-left', this.onGoLeft, this);
        this.node.on('go-right', this.onGoRight, this);
    }

    protected onDisable(): void {
        this.node.off('go-up', this.onGoUp, this);
        this.node.off('go-down', this.onGoDown, this);
        this.node.off('go-left', this.onGoLeft, this);
        this.node.off('go-right', this.onGoRight, this);
    }

    onGoUp() {
        // console.log(`onGoUp`);
        if (!this.p_GameStarted || this.p_Paused) { return; }
        this.board.toTurn();
    }

    onGoDown() {
        // console.log(`onGoDown`);
        if (!this.p_GameStarted || this.p_Paused) { return; }
        const mino = this.board.toGoDown()

        if (mino) {
            this.doGoDown(mino);
        }
    }

    onGoLeft() {
        // console.log(`onGoLeft`);
        if (!this.p_GameStarted || this.p_Paused) { return; }
        this.board.toGoLeft();
    }
    onGoRight() {
        // console.log(`onGoRight`);
        if (!this.p_GameStarted || this.p_Paused) { return; }
        this.board.toGoRight();
    }

    public startGame() {
        this.p_GameStarted = true;
        this.p_Paused = false;
        this.p_StartGameTS = Date.now();

        this.mainUI.updateScore(0);
        this.mainUI.updateHigh();
        this.doCreateOneMino();
    }

    public pauseGame() {
        this.p_Paused = true;
    }

    public resumeGame() {
        this.p_Paused = false;
    }

    public stopGame() {
        this.p_GameStarted = false;
        DataCenter.updateHigh();

        const ts = Date.now();
        const timespent = (ts - this.p_StartGameTS) / 1000 | 0;

        DataCenter.setTimeSpent(timespent);

        this.mainUI.gameover.initUI(DataCenter.getScore());
        this.audio.playGameOver();
        this.mainUI.gameover.showPopUp();
    }

    public clearGame() {
        this.speed = 1;
        this.board.clearAllMinos();
        DataCenter.clearScore();
        this.mainUI.updateScore(0);
    }

    public updateGame(dt: number) {
        this._interval += dt;
        if (this._interval < this.interval / this.speed) {
            return;
        }
        this._interval = 0;

        const score = DataCenter.getScore();
        this.speed = SpeedManager.getSpeed(score);

        const board = this.board;
        const mino = board.mino;

        if (board.checkDownIllegal(mino)) {

            board.onMinoDie(mino);

            if (board.checkGameOver(mino)) {
                this.onGameOver();
                return;
            }

            const fullRows = this.board.getFullLine();
            if (fullRows.length > 0) {
                this.onLineFull(fullRows.length);
                this.board.clearLines(fullRows);

                this.audio.playLineClear();
            }

            this.doCreateOneMino();

        } else {
            this.doGoDown(mino);
        }

        // 旧的判断
        // this.__updateGame(mino, board);
    }

    __updateGame(mino: Mino, board: Board) {

        if (mino.willDie) {
            board.onMinoDie(mino);

            if (board.checkGameOver(mino)) {
                this.onGameOver();
                return;
            }

            const fullRows = this.board.getFullLine();
            console.log(fullRows);
            if (fullRows.length > 0) {
                this.onLineFull(fullRows.length);
                this.board.clearLines(fullRows);

                this.audio.playLineClear();
            }

            this.doCreateOneMino();

        } else {
            if (board.checkDownIllegal(mino)) {
                mino.willDie = true;
            } else {
                this.doGoDown(mino);
            }
        }
    }

    protected doCreateOneMino() {
        this.board.doCreateOneMino();
        // this.audio.playBalloon();
    }

    protected doGoDown(mino: Mino) {
        mino.down();
        mino.updatePos();

        this.audio.playDrop();
    }

    protected onGameOver() {
        console.log('onGameOver: ' + DataCenter.getScore());
        this.stopGame();
    }

    onLineFull(count: number) {
        const deltaScore = count * 100 + count * (count - 1) / 2 * 150;
        const score = DataCenter.addScore(deltaScore);
        this.mainUI.updateScore(score);
    }

    private _interval = 0;
    protected update(dt: number): void {
        if (!this.p_GameStarted) return;
        if (this.p_Paused) return;

        this.updateGame(dt);
    }

    private _isInMenuAnim = false;
    onStartBtnClicked() {
        this.audio.playCursor();
        if (this._isInMenuAnim) {
            return;
        }
        this._isInMenuAnim = true;
        this.mainUI.enterGame(() => {
            this._isInMenuAnim = false;

            if (this.p_Paused) {
                this.resumeGame();
            } else {
                this.startGame();
            }
        });
    }

    onRestartBtnClicked() {
        this.audio.playCursor();
        if (this._isInMenuAnim) {
            return;
        }

        // clear first
        this.clearGame();

        this._isInMenuAnim = true;
        this.mainUI.enterGame(() => {
            this._isInMenuAnim = false;
            this.startGame();
        });
    }

    onPauseBtnClicked() {
        this.audio.playCursor();
        if (this._isInMenuAnim) {
            return;
        }

        this.p_Paused = true;

        this._isInMenuAnim = true;
        this.mainUI.enterMenu(() => {
            this._isInMenuAnim = false;
        });
    }

    onSettingsBtnClicked() {
        this.audio.playCursor();
        if (this._isInMenuAnim) {
            return;
        }
        this.mainUI.settings.showPopUp();
    }

    onProfileBtnClicked() {
        this.audio.playCursor();
        if (this._isInMenuAnim) {
            return;
        }

        this.mainUI.myprofile.initUI(
            DataCenter.getHigh(),
            DataCenter.getTotal(),
            DataCenter.getTime(),
            DataCenter.getGames()
        );

        this.mainUI.myprofile.showPopUp();
    }

    onHomeBtnClicked() {
        this.clearGame();
        this._isInMenuAnim = true;
        this.mainUI.enterMenu(() => {
            this._isInMenuAnim = false;
        })
    }
}
